<template>
    <div class="upload">
        <TitleTips :title="title" />
        <el-card v-for="(item, index) in formList" :key="index" class="mt-6">
            <div slot="header" class="flex justify-between">
                <span>序号{{ index + 1 }}</span>
                <i v-show="showDelete" class="text-xl text-red-500 cursor-pointer el-icon-delete" @click="handleDelete(index)" />
            </div>
            <el-form ref="ruleForm" label-width="88px" size="medium" :rules="rules" :model="item">
                <el-row :gutter="24">
                    <el-col :xl="6" :lg="8">
                        <el-form-item label="所属公路" prop="road.value.value">
                            <el-select v-model="item.road.value" class="w-full" placeholder="请选择" clearable @change="handleSelectDirection(item, index)">
                                <el-option
                                    v-for="r in raods"
                                    :key="r.highwayCode"
                                    :label="r.highwayName"
                                    :value="{ value: r.highwayCode, label: r.highwayName }"
                                />
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :xl="6" :lg="8">
                        <el-form-item label="方向" prop="direction.value.value">
                            <el-select
                                v-model="item.direction.value"
                                class="w-full"
                                placeholder="请选择"
                                clearable
                                @change="handleSelectDirection(item, index)"
                            >
                                <el-option v-for="d in DirectionOptions" :key="d.value" :label="d.label" :value="{ value: d.value, label: d.label }" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col :xl="6" :lg="8">
                        <el-form-item label="位置类型" prop="locationType.value">
                            <el-select
                                v-model="item.locationType.value"
                                :disabled="!item.direction.value.value || !item.road.value.value"
                                placeholder="请选择"
                                style="width: 100%"
                                @change="(value) => resetLocation(value, item, index)"
                            >
                                <el-option v-for="m in locationOptions" :key="m.value" :label="m.label" :value="m.value" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col v-if="item.locationType.value === 1" :xl="6" :lg="8">
                        <el-form-item label="缺陷位置" prop="facilities.value">
                            <el-cascader
                                v-model="item.facilities.value"
                                :disabled="!item.direction.value || !item.road.value"
                                class="w-full"
                                placeholder="请选择"
                                clearable
                                :props="{ value: 'all', label: 'name', lngLat: 'lngLat' }"
                                :options="item.facilityList.value"
                            />
                        </el-form-item>
                    </el-col>
                    <el-col v-if="item.locationType.value === 2" :xl="6" :lg="8">
                        <el-col :span="14" style="padding: 0">
                            <el-form-item label="桩号" prop="stake1.value" class="spe-item">
                                <el-input
                                    v-model.trim="item.stake1.value"
                                    :disabled="!item.direction.value || !item.road.value"
                                    placeholder="请输入"
                                    maxlength="3"
                                    @change="item.stake2.value = ''"
                                >
                                    <div slot="prepend" class="input-unit">K</div>
                                </el-input>
                            </el-form-item>
                        </el-col>
                        <el-col :span="10" style="padding: 0">
                            <el-form-item
                                class="spe-item spe-label"
                                label-width="30px"
                                label="+"
                                prop="stake2.value"
                                :rules="useCheckStake(item.road.value.value, item.direction.value.value, item.stake1.value, item.roadStake)"
                            >
                                <el-input v-model.trim="item.stake2.value" maxlength="3" :disabled="!item.stake1.value" placeholder="请输入" />
                            </el-form-item>
                        </el-col>
                    </el-col>
                    <el-col v-if="item.locationType.value === 3" :xl="12" :lg="16">
                        <el-col :span="7" style="padding: 0">
                            <el-form-item label="桩号范围" prop="startStake1.value">
                                <el-input
                                    v-model.trim="item.startStake1.value"
                                    :disabled="!item.direction.value || !item.road.value"
                                    placeholder="请输入"
                                    maxlength="3"
                                    @change="item.startStake2.value = ''"
                                >
                                    <div slot="prepend" class="input-unit">K</div>
                                </el-input>
                            </el-form-item>
                        </el-col>
                        <el-col :span="5" style="padding: 0">
                            <el-form-item
                                class="spe-item spe-label"
                                label-width="30px"
                                label="+"
                                prop="startStake2.value"
                                :rules="useCheckStake(item.road.value.value, item.direction.value.value, item.startStake1.value, item.roadStake)"
                            >
                                <el-input v-model.trim="item.startStake2.value" :disabled="!item.startStake1.value" maxlength="3" placeholder="请输入" />
                            </el-form-item>
                        </el-col>
                        <el-col :span="7" style="padding: 0">
                            <el-form-item class="spe-item spe-label" label-width="50px" label="~" prop="endStake1.value">
                                <el-input
                                    v-model.trim="item.endStake1.value"
                                    :disabled="!item.direction.value || !item.road.value"
                                    placeholder="请输入"
                                    maxlength="3"
                                    @change="item.endStake2.value = ''"
                                >
                                    <div slot="prepend" class="input-unit">K</div>
                                </el-input>
                            </el-form-item>
                        </el-col>
                        <el-col :span="5" style="padding: 0">
                            <el-form-item
                                class="spe-item spe-label"
                                label-width="30px"
                                label="+"
                                prop="endStake2.value"
                                :rules="useCheckStake(item.road.value.value, item.direction.value.value, item.endStake1.value, item.roadStake)"
                            >
                                <el-input v-model.trim="item.endStake2.value" maxlength="3" :disabled="!item.endStake1.value" placeholder="请输入" />
                            </el-form-item>
                        </el-col>
                    </el-col>

                    <!-- <el-col v-if="item.locationType.value === 4" :xl="6" :lg="8">
                        <el-form-item label="设备信息" prop="deviceInfo.value">
                            <el-input
                                v-model.trim="item.deviceInfo.value"
                                readonly
                                class="device-info"
                                placeholder="请选择"
                                @click.native="showDeviceDialog(index)"
                            />
                        </el-form-item>
                    </el-col> -->
                    <el-col v-if="!item.isDevice" :xl="6" :lg="8">
                        <el-form-item label="缺陷项目" prop="projectType.value">
                            <el-select v-model="item.projectType.value" class="w-full" placeholder="请选择" clearable>
                                <el-option v-for="p in projectDefectType" :key="p.id" :label="p.name" :value="p.id" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col v-if="!item.isDevice" :xl="6" :lg="8">
                        <el-form-item label="缺陷类型" prop="type.value">
                            <el-select v-model="item.type.value" class="w-full" placeholder="请选择" clearable>
                                <el-option v-for="t in typeDefect" :key="t.id" :label="t.name" :value="t.id" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                    <el-col v-if="!item.isDevice" :xl="6" :lg="8">
                        <el-form-item label="严重程度" prop="severity.value">
                            <el-select v-model="item.severity.value" class="w-full" placeholder="请选择" clearable>
                                <el-option v-for="m in severityOptions" :key="m.value" :label="m.label" :value="m.value" />
                            </el-select>
                        </el-form-item>
                    </el-col>

                    <el-col v-if="!item.isDevice" :xl="6" :lg="8">
                        <el-form-item label="缺陷数量">
                            <el-input
                                v-model.number.trim="item.quantity.value"
                                placeholder="请输入"
                                clearable
                                type="number"
                                oninput="if(value.length > 10) value = value.slice(0, 10)"
                                @input="handleQuantityChange({ item, index })"
                            />
                            <span v-show="item.quantity.show" class="el-form-item__error">{{ item.quantity.message }}</span>
                        </el-form-item>
                    </el-col>
                    <el-col v-if="!item.isDevice" :xl="6" :lg="8">
                        <el-form-item label="单位">
                            <el-input v-model.trim="item.unit.value" placeholder="请输入" clearable maxlength="4" show-word-limit />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-col :span="24">
                    <el-form-item label="缺陷说明">
                        <el-input
                            v-model.trim="item.description.value"
                            class="w-full"
                            placeholder="请输入"
                            clearable
                            type="textarea"
                            maxlength="200"
                            show-word-limit
                            :autosize="{ minRows: 6, maxRows: 10 }"
                        />
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="上传图片">
                        <el-upload
                            :action="action"
                            :headers="headers"
                            :accept="accept"
                            :limit="limit"
                            list-type="picture-card"
                            multiple
                            :file-list="item.photos.value"
                            :before-upload="beforeUpload"
                            :on-exceed="handleExceed"
                            :on-success="(response, file, fileList) => handleSuccess(response, file, fileList, index)"
                            :on-preview="handlePicturePreview"
                        >
                            <i class="el-icon-plus" />
                        </el-upload>
                        <el-dialog :visible.sync="dialogVisible">
                            <img width="100%" :src="dialogImageUrl" alt="" />
                        </el-dialog>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item v-if="!item.isDevice" label-width="100px" label="是否现场处理">
                        <el-radio-group v-model="item.dealType.value">
                            <el-radio :label="1">否</el-radio>
                            <el-radio :label="2">是</el-radio>
                        </el-radio-group>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item v-if="!item.isDevice && item.dealType.value === 2" label="处理记录" prop="processingRecords.value">
                        <el-input
                            v-model.trim="item.processingRecords.value"
                            class="w-full"
                            placeholder="请输入"
                            clearable
                            type="textarea"
                            maxlength="200"
                            show-word-limit
                            :autosize="{ minRows: 6, maxRows: 10 }"
                        />
                    </el-form-item>
                </el-col>
                <!-- 机电设备选中列表 -->
                <el-col v-if="item.isDevice" :span="24">
                    <el-form-item label="设备信息" prop="deviceResults.value">
                        <div class="device-table">
                            <div class="handle-header">
                                <el-button type="text" @click="showDeviceDialog(index)">选择设备</el-button>
                                <el-button :disabled="selectedList.length === 0" class="danger" type="text" @click="handleDeleteDevice(null)">
                                    批量移除
                                </el-button>
                            </div>
                            <BaseTable
                                v-if="item.deviceResults.value.length > 0"
                                :columns="columns"
                                :data="item.deviceResults.value"
                                max-height="500px"
                                highlight-current-row
                                @selection-change="handleSelectionChange"
                            >
                                <template #remake="{ scope: { row } }">
                                    <el-input v-model.trim="row.remake" placeholder="请输入，100字以内" maxlength="100" size="mini" type="table" />
                                </template>
                                <template #handle="{ scope: { row } }">
                                    <BaseButton type="text" color="danger" @click="handleDeleteDevice(row)"> 移除 </BaseButton>
                                </template>
                            </BaseTable>
                        </div>
                    </el-form-item>
                </el-col>
            </el-form>
        </el-card>
        <!-- 添加按钮 -->
        <div class="flex items-center justify-center w-full h-16 mt-6 bg-white border-2 border-gray-400 border-dotted cursor-pointer" @click="handleAdd">
            添加
        </div>
        <!-- 选择设备弹框表格 -->
        <el-dialog width="800px" :visible.sync="deviceDialogVisible" title="选择设备">
            <DeviceDialog
                :visible="deviceDialogVisible"
                :params="{
                    highwayCode: formList[formIndex].road.value.value,
                    direction: formList[formIndex].direction.value.label
                }"
                @close="deviceDialogVisible = false"
                @get-list="getDeviceList"
            />
        </el-dialog>
    </div>
</template>
<script>
import { getToken } from '@/utils/auth'
import { UploadOption, DirectionOptions, SeverityOptions } from '@/config/constants'
import { mapState } from 'vuex'
import useConfirm from '@/hooks/useConfirm'
import { cloneDeep, uniqBy } from 'lodash-es'
import useCheckStake from '@/hooks/useCheckStake'
import reconfirm from '@/utils/reconfirm'
import { fileTokenKey } from '@/config/settings'
import { isInteger } from '@/utils/validate'

const formItem = {
    // 缺陷类型
    type: {
        value: null
    },
    // 项目缺陷
    projectType: {
        value: null
    },
    // 缺陷数量
    quantity: {
        show: false,
        value: null,
        message: '请输入大于0的数值'
    },
    // 缺陷单位
    unit: {
        value: null
    },
    // 所属公路
    road: {
        value: {}
    },
    // 所属方向
    direction: {
        value: {}
    },
    // 设施名称
    facilities: {
        value: null
    },
    // 设施选项
    facilityList: {
        value: []
    },
    // 缺陷位置开始1
    startStake1: {
        value: null
    },
    // 缺陷位置开始2
    startStake2: {
        value: null
    },
    // 缺陷位置结束1
    endStake1: {
        value: null
    },
    // 缺陷位置结束2
    endStake2: {
        value: null
    },
    deviceInfo: {
        value: null
    },
    // 缺陷说明
    description: {
        value: null
    },
    // 图片
    photos: {
        value: []
    },
    // 处理方式
    dealType: {
        value: 1
    },
    // 处理记录
    processingRecords: {
        value: null
    },
    locationType: {
        value: 1
    },
    facilityCode: {
        value: []
    },
    stake1: {
        value: null
    },
    stake2: {
        value: null
    },
    severity: {
        value: null
    },
    deviceResults: {
        value: []
    }
}
export default {
    name: 'FlawForm',
    props: {
        value: {
            type: Object,
            default: () => {}
        },
        title: {
            type: String,
            default: '缺陷内容'
        }
    },
    data() {
        return {
            DirectionOptions,
            locationOptions: Object.freeze([
                {
                    value: 1,
                    label: '设施'
                },
                {
                    value: 2,
                    label: '桩号'
                },
                {
                    value: 3,
                    label: '桩号范围'
                },
                {
                    value: 4,
                    label: '机电设备'
                }
            ]),
            severityOptions: SeverityOptions,
            validates: [],
            dialogVisible: false,
            dialogImageUrl: '',
            headers: {
                [fileTokenKey]: getToken()
            },
            limit: UploadOption.LIMIT,
            action: UploadOption.ACTION,
            accept: UploadOption.ACCEPT,
            formList: [cloneDeep(formItem)],
            rules: {
                'type.value': [{ required: true, message: '请选择缺陷类型', trigger: 'change' }],
                'projectType.value': [{ required: true, message: '请选择缺陷项目', trigger: 'change' }],
                'road.value.value': [{ required: true, message: '请选择所属公路', trigger: 'change' }],
                'direction.value.value': [{ required: true, message: '请选择方向', trigger: 'change' }],
                'startStake1.value': [
                    { required: true, message: '请输入起始桩号', trigger: 'blur' },
                    { required: true, validator: this.validNum, trigger: 'blur' }
                ],
                'stake1.value': [
                    { required: true, message: '请输入桩号', trigger: 'blur' },
                    { required: true, validator: this.validNum, trigger: 'blur' }
                ],
                'endStake1.value': [
                    { required: true, message: '请输入结束桩号', trigger: 'blur' },
                    { required: true, validator: this.validNum, trigger: 'blur' }
                ],
                'processingRecords.value': [{ required: true, message: '请输入处理记录', trigger: 'blur' }],
                'facilities.value': [{ required: true, message: '请选择缺陷位置', trigger: 'change' }],
                'severity.value': [{ required: true, message: '请选择严重程度', trigger: 'change' }],
                'locationType.value': [{ required: true, message: '请选择位置类型', trigger: 'change' }],
                'deviceInfo.value': [{ required: true, message: '请选择设备信息', trigger: 'change' }],
                'deviceResults.value': [{ required: true, message: '请选择设备', trigger: ['change', 'blur'] }]
            },
            deviceDialogVisible: false,
            formIndex: 0,
            selectedList: [],
            deviceList: [],
            columns: Object.freeze([
                {
                    attrs: {
                        type: 'selection'
                    }
                },
                {
                    attrs: {
                        prop: 'number',
                        label: '设备编号',
                        'show-overflow-tooltip': true,
                        width: '200'
                    }
                },
                {
                    attrs: {
                        prop: 'name',
                        label: '设备名称',
                        'min-width': '140',
                        'show-overflow-tooltip': true
                    }
                },
                {
                    slot: 'remake',
                    attrs: {
                        label: '故障现象(原因)',
                        'min-width': '160',
                        'show-overflow-tooltip': true
                    }
                },
                {
                    slot: 'handle',
                    attrs: {
                        label: '操作',
                        width: '120',
                        fixed: 'right'
                    }
                }
            ])
        }
    },
    computed: {
        ...mapState(['raods', 'facilityList']),
        ...mapState('types', ['typeDefect', 'projectDefectType']),
        showDelete() {
            return this.formList?.length > 1
        }
    },
    watch: {
        formList: {
            handler() {
                const formData = {
                    pass: true,
                    list: []
                }
                this.formList.forEach((c) => {
                    const obj = {}
                    for (const key in c) {
                        if (Object.hasOwnProperty.call(c, key)) {
                            const ele = c[key]
                            if (ele.show) {
                                formData.pass = false
                            }
                            if (key === 'photos') {
                                obj.photos = ele?.value
                                    ?.map((file) => {
                                        return file?.response?.data?.objectUrl
                                    })
                                    .join(',')
                            } else {
                                obj[key] = ele.value
                            }
                            // 单独处理下桩号参数，后端要的是stake
                            obj.stake = obj.stake1 ? `K${obj.stake1}+${obj.stake2 || '000'}` : null
                        }
                    }
                    formData.list.push(obj)
                })
                this.$emit('input', formData)
            },
            deep: true
        }
    },
    created() {
        this.generateOption()
    },
    methods: {
        validNum(rule, value, callback) {
            if (value && !isInteger(value)) {
                callback(new Error('请输入数字'))
            } else {
                callback()
            }
        },
        // 设施列表选择
        handleSelectionChange(val) {
            this.selectedList = val
        },
        // 设施列表批量和单个删除
        handleDeleteDevice(row) {
            reconfirm({
                isPromise: false,
                callback: () => {
                    const selectedList = row ? [row] : this.selectedList
                    const deviceList = this.formList[this.formIndex].deviceResults.value
                    this.formList[this.formIndex].deviceResults.value = this.filterSeletedArray(selectedList, deviceList)
                }
            })
        },
        filterSeletedArray(selectedArr, arr, key = 'id') {
            selectedArr.forEach((item) => {
                arr = arr.filter((m) => m[key] !== item[key])
            })
            return arr
        },
        getDeviceList(val) {
            const arr = [...this.formList[this.formIndex].deviceResults.value].concat(val)
            this.formList[this.formIndex].deviceResults.value = uniqBy(arr, 'id')
            // 当添加设备后，清除设备信息的验证提示
            this.$refs['ruleForm'][this.formIndex].clearValidate('deviceResults.value')
        },
        resetLocation(val, item, index) {
            // 对应form验证清除，值清空
            this.$refs['ruleForm'][index].clearValidate([
                'facilities.value',
                'startStake1.value',
                'startStake2.value',
                'endStake1.value',
                'endStake2.value',
                'stake1.value',
                'stake2.value'
            ])
            item.facilities.value = []
            item.startStake1.value = ''
            item.startStake2.value = ''
            item.endStake1.value = ''
            item.endStake2.value = ''
            item.stake1.value = ''
            item.stake2.value = ''
            // 判断是否为机电设备权限，如果是，是否现场处理选项隐藏
            item.isDevice = val === 4
        },
        showDeviceDialog(index) {
            this.deviceDialogVisible = true
            this.formIndex = index
        },
        generateOption(option = []) {
            option &&
                option.forEach((item) => {
                    item.all = { value: item.id, label: item.name, lngLat: item.lngLat }
                    item.children && this.generateOption(item.children)
                })
            return option
        },
        async handleSelectDirection(item, index) {
            // 把位置类型下的选项值权全清空
            this.resetLocation(item.locationType.value, item, index)
            // 设施列表和设备列表都清空
            this.formList[index].facilities.value = []
            this.formList[index].deviceResults.value = []

            if (item?.road?.value?.value && item?.direction?.value?.value) {
                const data = {
                    roadCode: item?.road?.value?.value,
                    direction: item?.direction?.value?.value
                }
                console.log('data :>> ', data)
                const res = await this.$store.dispatch('getFacilityList', data)
                this.generateOption(res)
                this.formList[index].facilityList.value = res
            }
            // 获取当前高速桩号范围，用于桩号错误提示
            const roadCode = item?.road?.value?.value
            if (roadCode) {
                this.raods.some((m) => {
                    if (m.highwayCode === roadCode) {
                        // 当前项添加桩号范围roadStake
                        // item.roadStake = `${m.startStakeNo}~${m.endStakeNo}`
                        this.$set(item, 'roadStake', `${m.startStakeNo}~${m.endStakeNo}`)
                        return true
                    }
                })
            }
        },
        async submitForm() {
            const list = []
            const validas = []
            this.$refs['ruleForm'].forEach((item, index) => {
                // 把单个验证结果处理为promise函数，然后添加到list中
                list.push(
                    new Promise((resolve) => {
                        item.validate((valida) => {
                            validas.push(valida)
                            resolve()
                        })
                    })
                )
            })
            // 通过Promise.all等待几个验证都完成再处理
            return Promise.all([...list])
                .then(() => {
                    const res = !validas.some((item) => item === false)
                    return res
                })
                .catch(() => {
                    return false
                })
        },
        handleAdd() {
            this.formList.push(cloneDeep(formItem))
        },
        async handleDelete(index) {
            await useConfirm({
                text: '是否确定删除当前内容'
            })
            this.formList.splice(index, 1)
        },
        handleQuantityChange({ item, index }) {
            // input为number的时候maxlength 会失效，如下处理限制20位数
            const value = `${item.quantity.value}`
            const maxlength = 20
            if (value.length > maxlength) {
                this.formList[index].quantity.value = +value.slice(0, maxlength)
                console.log(this.formList[index].quantity.value)
            }
            if (item.quantity.value <= 0) {
                this.formList[index].quantity.show = true
            } else {
                this.formList[index].quantity.show = false
            }
        },
        handleIsDealChange({ item, index }) {
            if (item.isDeal.value) {
                this.formList[index].isDeal.show = true
            } else {
                this.formList[index].isDeal.show = false
            }
        },
        handleRecordChange({ item, index }) {
            if (item.processingRecords.value) {
                this.formList[index].isDeal.show = false
            } else {
                this.formList[index].isDeal.show = true
            }
        },
        beforeUpload(file) {
            const isLt10M = file.size / 1024 / 1024 < 10
            if (!isLt10M) {
                this.$message.warning('上传图片大小不能超过10MB!')
            }
            return isLt10M
        },
        handleExceed(files, fileList) {
            if (fileList?.length >= this.limit) {
                this.$message.warning(`已经上传 ${this.limit}张图片，不能再上传了`)
                return
            }
            this.$message.warning(`最多上传 ${this.limit} 张照片，本次选择了 ${files.length} 个照片`)
        },
        handleSuccess(response, file, fileList, index) {
            this.formList[index].photos.value = fileList
        },
        handlePicturePreview(file) {
            this.dialogImageUrl = file.url
            this.dialogVisible = true
        },
        useCheckStake
    }
}
</script>

<style lang="scss" scoped>
.spe-item {
    &.spe-label ::v-deep .el-form-item__label {
        text-align: center;
        padding: 0;
        &::before {
            display: none;
        }
    }
    ::v-deep {
        .el-input,
        .el-input__inner {
            min-width: auto !important;
        }
    }
}
.device-info {
    ::v-deep {
        .el-input__inner {
            cursor: pointer;
        }
    }
}
</style>
